package com.csjbot.coshandler.core;

import android.content.Context;
import android.graphics.Bitmap;

import com.csjbot.cosclient.utils.CosLogger;
import com.csjbot.coshandler.core.interfaces.IAction;
import com.csjbot.coshandler.core.interfaces.IChassis;
import com.csjbot.coshandler.core.interfaces.IExpression;
import com.csjbot.coshandler.core.interfaces.IFace;
import com.csjbot.coshandler.core.interfaces.ISpeech;
import com.csjbot.coshandler.global.ConnectConstants;
import com.csjbot.coshandler.global.REQConstants;
import com.csjbot.coshandler.listener.OnArmWaveListener;
import com.csjbot.coshandler.listener.OnCameraListener;
import com.csjbot.coshandler.listener.OnChargetStateListener;
import com.csjbot.coshandler.listener.OnChassisListener;
import com.csjbot.coshandler.listener.OnDeviceInfoListener;
import com.csjbot.coshandler.listener.OnExpressionListener;
import com.csjbot.coshandler.listener.OnFaceListener;
import com.csjbot.coshandler.listener.OnFaceSaveListener;
import com.csjbot.coshandler.listener.OnGetVersionListener;
import com.csjbot.coshandler.listener.OnHeadTouchListener;
import com.csjbot.coshandler.listener.OnInitListener;
import com.csjbot.coshandler.listener.OnMapListener;
import com.csjbot.coshandler.listener.OnMicroVolumeListener;
import com.csjbot.coshandler.listener.OnNaviSearchListener;
import com.csjbot.coshandler.listener.OnPositionListener;
import com.csjbot.coshandler.listener.OnRobotStateListener;
import com.csjbot.coshandler.listener.OnSNListener;
import com.csjbot.coshandler.listener.OnSetSNListener;
import com.csjbot.coshandler.listener.OnSnapshotoListener;
import com.csjbot.coshandler.listener.OnSpeakListener;
import com.csjbot.coshandler.listener.OnSpeechErrorListener;
import com.csjbot.coshandler.listener.OnSpeechListener;
import com.csjbot.coshandler.listener.OnSpeedSetListener;
import com.csjbot.coshandler.listener.OnWakeupListener;
import com.csjbot.coshandler.log.Csjlogger;
import com.csjbot.coshandler.tts.ISpeechSpeak;
import com.csjbot.coshandler.tts.SpeechFactory;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * 对外提供的机器人功能类
 * Created by jingwc on 2017/9/5.
 */

public class Robot implements IFace, IAction, ISpeech, IExpression, IChassis {

    private volatile static Robot robot;

    /* 所以基础请求的代理类 */
    public ClientReqProxy reqProxy;

    /* 语音合成类 */
    private ISpeechSpeak speechSpeak;

    private OnSpeechListener speechListener;
    private OnFaceListener faceListener;
    private OnExpressionListener expressionListener;
    private OnInitListener initListener;
    private OnCameraListener cameraListener;
    private OnChassisListener chassisListener;
    private OnPositionListener positionListener;
    private OnSNListener snListener;
    private OnDeviceInfoListener deviceInfoListener;
    private OnRobotStateListener robotStateListener;
    private OnSnapshotoListener snapshotoListener;
    private OnFaceSaveListener faceSaveListener;
    private OnSetSNListener setSNListener;
    private OnSpeechErrorListener speechErrorListener;
    private OnMapListener mapListener;
    private OnGetVersionListener getVersionListener;
    private OnWakeupListener wakeupListener;
    private OnSpeedSetListener speedSetListener;
    private OnMicroVolumeListener microVolumeListener;
    private OnArmWaveListener armWaveListener;
    private OnHeadTouchListener headTouchListener;
    private OnNaviSearchListener onNaviSearchListener;
    private OnChargetStateListener onChargetStateListener;

    public static Robot getInstance() {
        if (robot == null) {
            synchronized (Robot.class) {
                if (robot == null) {
                    robot = new Robot();
                }
            }
        }
        return robot;
    }

    private Robot() {
        reqProxy = new ClientReqProxy();
    }

    /**
     * 初始化语音合成
     *
     * @param context
     */
    @Override
    public void initSpeak(Context context) {
        speechSpeak = SpeechFactory.createSpeech(context, SpeechFactory.SpeechType.IFLY);
    }

    public void setSpeechListener(OnSpeechListener listener) {
        speechListener = listener;
    }

    public void setFaceListener(OnFaceListener listener) {
        faceListener = listener;
    }

    public void setExpressionListener(OnExpressionListener listener) {
        expressionListener = listener;
    }

    public void setInitListener(OnInitListener listener) {
        initListener = listener;
    }

    public void setCameraListener(OnCameraListener listener) {
        cameraListener = listener;
    }

    public void setChassisListener(OnChassisListener listener) {
        chassisListener = listener;
    }

    public void setPositionListener(OnPositionListener listener) {
        positionListener = listener;
    }

    public void setSnListener(OnSNListener listener) {
        snListener = listener;
    }

    public void setDeviceInfoListener(OnDeviceInfoListener listener) {
        deviceInfoListener = listener;
    }

    public void setRobotStateListener(OnRobotStateListener listener) {
        robotStateListener = listener;
    }

    public void setSnapshotoListener(OnSnapshotoListener listener) {
        snapshotoListener = listener;
    }

    public void setFaceSaveListener(OnFaceSaveListener listener) {
        faceSaveListener = listener;
    }

    public void setSpeechErrorListener(OnSpeechErrorListener listener) {
        speechErrorListener = listener;
    }

    public void setMapListener(OnMapListener listener) {
        mapListener = listener;
    }

    public void setGetVersionListener(OnGetVersionListener listener) {
        getVersionListener = listener;
    }

    public void setWakeupListener(OnWakeupListener listener) {
        wakeupListener = listener;
    }

    public void setSpeedSetListener(OnSpeedSetListener speedSetListener) {
        this.speedSetListener = speedSetListener;
    }

    public void setMicroVolumeListener(OnMicroVolumeListener listener) {
        this.microVolumeListener = listener;
    }

    public void setHeadTouchListener(OnHeadTouchListener listener) {
        this.headTouchListener = listener;
    }

    public void setOnNaviSearchListener(OnNaviSearchListener onNaviSearchListener) {
        this.onNaviSearchListener = onNaviSearchListener;
    }

    public void setOnChargetStateListener(OnChargetStateListener onChargetStateListener) {
        this.onChargetStateListener = onChargetStateListener;
    }

    public void pushChargeState(int state) {
        if (onChargetStateListener != null) {
            onChargetStateListener.response(state);
        }
    }

    public void pushHeadTouch() {
        if (headTouchListener != null) {
            headTouchListener.response();
        }
    }

    public void pushMicrolVolume(int volume) {
        if (microVolumeListener != null) {
            microVolumeListener.response(volume);
        }
    }

    public void setArmWaveListener(OnArmWaveListener armWaveListener) {
        this.armWaveListener = armWaveListener;
    }

    public void pushWakeup() {
        if (wakeupListener != null) {
            wakeupListener.response();
        }
    }

    public void pushVersion(String version) {
        if (getVersionListener != null) {
            getVersionListener.response(version);
        }
    }

    public void pushLoadMap(boolean state) {
        if (mapListener != null) {
            mapListener.loadMap(state);
        }

    }

    public void pushSaveMap(boolean state) {
        if (mapListener != null) {
            mapListener.saveMap(state);
        }
    }

    public void pushSetSpeed(String json) {
        try {
            JSONObject jo = new JSONObject(json);
            int error_code = jo.optInt("error_code");
            if (error_code == 0 && speedSetListener != null) {
                speedSetListener.setSpeedResult(true);
            } else if (error_code != 0 && speedSetListener != null) {
                speedSetListener.setSpeedResult(false);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void pushNaviSearchResult(String json) {
        if (onNaviSearchListener != null)
            onNaviSearchListener.searchResult(json);
    }

    public void pushSpeechError() {
        if (speechErrorListener != null) {
            speechErrorListener.response();
        }
    }

    public void pushFaceSave(String json) {
        if (faceSaveListener != null) {
            faceSaveListener.response(json);
        }
    }

    public void pushSnapshoto(String json) {
        if (snapshotoListener != null) {
            snapshotoListener.response(json);
        }
    }

    public void setSnListener(OnSetSNListener listener) {
        if (setSNListener != null) {
            setSNListener = listener;
        }
    }

    public void pushCancelTask(String json) {
        if (positionListener != null) {
            positionListener.cancelResult(json);
        } else {
            Csjlogger.debug("positionListener为空");
        }
    }

    public void pushArmWaveResult(String json) {
        if (armWaveListener != null) {
            armWaveListener.start(json);
        }
    }

    public void pushArmStopResult(String json) {
        if (armWaveListener != null) {
            armWaveListener.stop(json);
        }
    }

//    public void pushArmStartWaveResult

    /**
     * 推送发送
     *
     * @param json
     */
    public void pushMoveToResult(String json) {
        if (positionListener != null) {
            positionListener.moveToResult(json);
        }
    }

    public void pushPosition(String json) {
        if (positionListener != null) {
            positionListener.positionInfo(json);
        }
    }

    public void pushMoveResult(String json) {
        if (positionListener != null) {
            CosLogger.debug("接口回调调用了");
            positionListener.moveResult(json);
        }
    }

    /**
     * 向上推送语音识别结果
     *
     * @param json
     */
    public void pushSpeech(String json, int type) {
        if (speechListener != null) {
            speechListener.speechInfo(json, type);
        }
    }

    /**
     * 向上推送人脸识别信息
     *
     * @param json
     */
    public void pushFace(String json) {
        if (faceListener != null) {
            faceListener.personInfo(json);
        }
    }

    /**
     * 向上推送人脸检测靠近信息
     *
     * @param person
     */
    public void pushFace(boolean person) {
        if (faceListener != null) {
            faceListener.personNear(person);
        }
    }

    /**
     * 向上推送人脸数据库信息
     *
     * @param json
     */
    public void pushFaceList(String json) {
        if (faceListener != null) {
            faceListener.personList(json);
        }
    }

    /**
     * 向上推送当前表情
     *
     * @param expression
     */
    public void pushExpression(int expression) {
        if (expressionListener != null) {
            expressionListener.response(expression);
        }
    }

    /**
     * 向上推送视频流
     *
     * @param bitmap
     */
    public void pushCamera(Bitmap bitmap) {
        if (cameraListener != null) {
            cameraListener.response(bitmap);
        }
    }

    /**
     * 向上推送init状态信息
     *
     * @param type
     */
    public void pushInit(int type) {
        if (initListener != null) {
            switch (type) {
                case ConnectConstants.ConnectStatus.SUCCESS:
                    initListener.success();
                    break;
                case ConnectConstants.ConnectStatus.FAILD:
                    initListener.faild();
                    break;
                case ConnectConstants.ConnectStatus.TIMEOUT:
                    initListener.timeout();
                    break;
                case ConnectConstants.ConnectStatus.DISCONNECT:
                    initListener.disconnect();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 向上推送 sn 信息
     *
     * @param sn 机器人 SN
     */
    public void pushSN(String sn) {
        if (snListener != null) {
            snListener.response(sn);
        }
    }

    /**
     * 向上推送机器人上身板等设备信息
     *
     * @param info 设备信息
     */
    public void pushDeviceInfo(String info) {
        if (deviceInfoListener != null) {
            deviceInfoListener.response(info);
        }
    }

    /**
     * 向上推送设置 SN 信息
     */
    public void pushSetSnResp(String info) {
        if (setSNListener != null) {
            setSNListener.response(info);
        }
    }

    /**
     * 向上推送机器人电量信息
     *
     * @param battery
     */
    public void pushRobotState(int battery) {
        if (robotStateListener != null) {
            robotStateListener.getBattery(battery);
        }
    }

    @Override
    public void leftLargeArmUp() {
        reqProxy.action(REQConstants.BodyPart.LEFT_ARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void leftLargeArmDown() {
        reqProxy.action(REQConstants.BodyPart.LEFT_ARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void leftSmallArmUp() {
        reqProxy.action(REQConstants.BodyPart.LEFT_FOREARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void leftSmallArmDown() {
        reqProxy.action(REQConstants.BodyPart.LEFT_FOREARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void righLargeArmUp() {
        reqProxy.action(REQConstants.BodyPart.RIGHT_ARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void rightLargeArmDown() {
        reqProxy.action(REQConstants.BodyPart.RIGHT_ARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void rightSmallArmUp() {
        reqProxy.action(REQConstants.BodyPart.RIGHT_FOREARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void rightSmallArmDown() {
        reqProxy.action(REQConstants.BodyPart.RIGHT_FOREARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void doubleLargeArmUp() {
        reqProxy.action(REQConstants.BodyPart.DOUBLE_ARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void doubleLargeArmDown() {
        reqProxy.action(REQConstants.BodyPart.DOUBLE_ARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void doubleSmallArmUp() {
        reqProxy.action(REQConstants.BodyPart.DOUBLE_FOREARM, REQConstants.BodyAction.LEFT_UP);
    }

    @Override
    public void doubleSmallArmDown() {
        reqProxy.action(REQConstants.BodyPart.DOUBLE_FOREARM, REQConstants.BodyAction.RIGHT_DOWN);
    }

    @Override
    public void startWave(int intervalTime) {
        reqProxy.startWaveHands(intervalTime);
    }

    @Override
    public void stopWave() {
        reqProxy.stopWaveHands();
    }

    @Override
    public void snowRightArm() {
        reqProxy.action(1, 1);
    }

    @Override
    public void snowLeftArm() {
        reqProxy.action(2, 1);
    }

    @Override
    public void snowDoubleArm() {
        reqProxy.action(3, 1);
    }

    /**
     * 摇头动作
     */
    @Override
    public void denyAction() {
        reqProxy.action(REQConstants.BodyPart.HEAD, REQConstants.BodyAction.LEFT_THEN_RIGHT);
    }

    /**
     * 点头动作
     */
    @Override
    public void nodAction() {
        reqProxy.action(REQConstants.BodyPart.HEAD, REQConstants.BodyAction.UP_AND_DOWN);
    }

    /**
     * 重置动作
     */
    @Override
    public void resetAction() {
        reqProxy.action(REQConstants.BodyPart.RESET, REQConstants.BodyAction.NONE);
    }

    public void expression(int expression) {
        reqProxy.setExpression(expression
                , REQConstants.Expression.NO
                , REQConstants.Expression.NO);
    }

    /**
     * 开心表情
     */
    @Override
    public void happy() {
        expression(REQConstants.Expression.HAPPY);
    }

    /**
     * 悲伤表情
     */
    @Override
    public void sadness() {
        expression(REQConstants.Expression.SADNESS);
    }

    /**
     * 惊讶表情
     */
    @Override
    public void surprised() {
        expression(REQConstants.Expression.SURPRISED);
    }

    /**
     * 微笑表情
     */
    @Override
    public void smile() {
        expression(REQConstants.Expression.SMILE);
    }

    /**
     * 普通表情
     */
    @Override
    public void normal() {
        expression(REQConstants.Expression.NORMAL);
    }

    /**
     * 生气表情
     */
    @Override
    public void angry() {
        expression(REQConstants.Expression.ANGRY);
    }

    /**
     * 开始说话
     *
     * @param text
     * @param listener
     */
    @Override
    public void startSpeaking(String text, OnSpeakListener listener) {
        if (speechSpeak != null) {
            speechSpeak.startSpeaking(text, listener);
        }
    }

    /**
     * 停止说话
     */
    @Override
    public void stopSpeaking() {
        if (speechSpeak != null) {
            speechSpeak.stopSpeaking();
        }
    }

    /**
     * 暂停说话
     */
    @Override
    public void pauseSpeaking() {
        if (speechSpeak != null) {
            speechSpeak.pauseSpeaking();
        }
    }

    /**
     * 重新说话
     */
    @Override
    public void resumeSpeaking() {
        if (speechSpeak != null) {
            speechSpeak.resumeSpeaking();
        }
    }

    @Override
    public boolean isSpeaking() {
        return speechSpeak != null ? speechSpeak.isSpeaking() : false;
    }

    @Override
    public void turnLeft() {
        reqProxy.moveAngle(1);
    }

    @Override
    public void turnRight() {
        reqProxy.moveAngle(-1);
    }

    @Override
    public void moveLeft() {
        reqProxy.move(REQConstants.MoveDirection.LEFT);
    }

    @Override
    public void moveRight() {
        reqProxy.move(REQConstants.MoveDirection.RIGHT);
    }

    @Override
    public void moveForward() {
        reqProxy.move(REQConstants.MoveDirection.FORWARD);
    }

    @Override
    public void moveBack() {
        reqProxy.move(REQConstants.MoveDirection.BACK);
    }

}
